home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 05.zip / BS1 part 5 / SASC_6.0_Disk_7.adf / Source_And_Examples / source / cback.a < prev    next >
Encoding:
Text File  |  1992-07-30  |  21.2 KB  |  621 lines

  1. *
  2. * C initial startup procedure under AmigaDOS
  3.  
  4.         INCLUDE "exec/types.i"
  5.         INCLUDE "exec/alerts.i"
  6.         INCLUDE "exec/nodes.i"
  7.         INCLUDE "exec/lists.i"
  8.         INCLUDE "exec/ports.i"
  9.         INCLUDE "exec/libraries.i"
  10.         INCLUDE "exec/tasks.i"
  11.         INCLUDE "exec/memory.i"
  12.         INCLUDE "exec/execbase.i"
  13.         INCLUDE "libraries/dos.i"
  14.         INCLUDE "libraries/dosextens.i"
  15. FUNCDEF         MACRO   * function
  16. _LVO\1          EQU     FUNC_CNT
  17. FUNC_CNT        SET     FUNC_CNT-6
  18.                 ENDM
  19.  
  20. FUNC_CNT        SET     LIB_NONSTD
  21.  
  22.         INCLUDE "exec/exec_lib.i"
  23.         INCLUDE "libraries/dos_lib.i"
  24.         INCLUDE "workbench/startup.i"
  25.  
  26. AbsExecBase EQU 4
  27.  
  28. TINY    EQU     0
  29. callsys macro
  30.         CALLLIB _LVO\1
  31.         endm
  32.         
  33.         xdef        _XCEXIT               ; exit(code) is standard way to leave C.
  34.         xdef         @_XCEXIT
  35.         
  36.         xref        LinkerDB              ; linker defined base value
  37.         xref        _BSSBAS               ; linker defined base of BSS
  38.         xref        _BSSLEN               ; linker defined length of BSS
  39.  
  40.         xref        __main                ; Name of C program to start with.
  41.         xref        __fpinit              * initialize floating point
  42.         xref        __fpterm              * terminate floating point
  43.  
  44. *        library references
  45.  
  46.         csect       _NOMERGE,0,0,0,4
  47.         xref        _MemCleanup
  48.         xref        __savecli
  49.         xref        __freecli
  50.         xref        FindTask
  51.  
  52. start:
  53.         movem.l d1-d6/a0-a6,-(a7)
  54. REGSIZE EQU     (6+7)*4
  55.         lea     REGSIZE(a7),A5         * determine old stack pointer
  56.         move.l  a0,a2                  * save command pointer
  57.         move.l  d0,d2                  * and command length
  58.         lea     LinkerDB,a4            * load base register
  59.  
  60.         move.l  AbsExecBase.W,a6
  61.         move.l  a6,SysBase(A4)
  62.         move.l  a7,_StackPtr(A4)       * Save stack ptr
  63.         clr.l   _WBenchMsg(A4)
  64.  
  65. *------        Clear out our BSS section
  66.         lea     _BSSBAS,a3             * get base of BSS
  67.         moveq   #0,d1
  68.         move.l  #_BSSLEN,d0            * get length of BSS in longwords
  69.         bra.s   clr_lp                 * and clear for length given
  70. clr_bss move.l  d1,(a3)+
  71. clr_lp  dbf     d0,clr_bss
  72.  
  73. *------ get the address of our task
  74.         move.l        ThisTask(a6),A3
  75.  
  76. *-----  clear any pending signals
  77.         moveq        #0,d0
  78.         move.l       #$00003000,d1
  79.         callsys      SetSignal
  80.  
  81. *------ are we running as a son of Workbench?
  82.         move.l       pr_CurrentDir(A3),__curdir(A4)
  83.         tst.l        pr_CLI(A3)
  84.         beq          fromWorkbench
  85.  
  86. *=======================================================================
  87. *====== CLI Startup Code ===============================================
  88. *=======================================================================
  89.  
  90. fromCLI:
  91. *------        attempt to open DOS library:
  92.         bsr.w        openDOS
  93.  
  94. *------ Duplicate the current directory for the called process
  95.         move.l        __curdir(A4),D1
  96.         move.l        DOSBase(A4),A6
  97.         callsys       DupLock
  98.         move.l        D0,__curdir(A4)
  99.  
  100. *------ Save the current CLI info including path for child to use
  101.         pea            cli
  102.         jsr            __savecli(pc)   
  103.         addq.l         #4,a7
  104.  
  105. *------ find command name:
  106.         move.l        pr_CLI(A3),a0
  107.         add.l         a0,a0                        ; bcpl pointer conversion
  108.         add.l         a0,a0
  109.         move.l        cli_CommandName(a0),a1
  110.         add.l         a1,a1                        ; bcpl pointer conversion
  111.         add.l         a1,a1
  112.  
  113. *------        collect parameters:
  114.         move.l        d2,d0                        ; get command line length
  115.         moveq.l       #0,d1
  116.         move.b        (a1)+,d1
  117.         move.l        A1,D4                        ;save our pointer
  118.         move.l        d1,d3
  119.         add.l         d1,d1                        ; double length since we copy it twice
  120.         add.l         d1,d0                        ; add length of command name
  121.         addq.l        #5,d0                        ; allow for space after command        
  122.         addq.l        #4,d0                        ; As well as for the roundup
  123. *                          ; changed from 5 to 9 for quotes
  124. *                                         
  125. *------        We have the length of the command string to be copied.
  126. *------        Allocate space for it.
  127. *------        Round up to the nearest 4 bytes
  128.         lsl.l         #2,d0
  129.         add.l         memsize(A4),d0
  130.         move.l        d0,memsize(A4)
  131.  
  132. ************************************************************************
  133. ************************************************************************
  134. ******** Allocate and copy over the code to do the magic stuff *********
  135. ************************************************************************
  136. ************************************************************************
  137.  
  138.         lea           memlist(A4),A0
  139.         move.l        AbsExecBase.W,a6
  140.         callsys       AllocEntry                ;get a place to put the code
  141. *        btst.l        #31,d0                     ;did we get the memory we asked for?
  142. *        beq           cliexit                    ;no, can't do anything then
  143.         move.l        D0,A1
  144.         move.l        D0,-(A7)                  ;remember the chunk we allocated
  145.  
  146. *------ Now we copy the code over
  147.         movea.l       ML_SIZE+ME_ADDR(A1),A1   ;locate our allocated block
  148.  
  149. *------        Copy over the command line to the allocated area
  150.         lea           commandbuf-copybeg(A1),A3
  151.  
  152. *------        At this point, we have:
  153. *                A0 - Work pointer
  154. *                A1 - Pointer to Allocated memory block
  155. *                A2 - Pointer to program name
  156. *                A3 - Pointer to target buffer
  157. *                A3 - Pointer to our process structure
  158. *                D0 - Work register
  159. *                D1 - Work register
  160. *                D2 - length of command name
  161. *                D3 - length of program name
  162. *                D4 - Pointer to program name
  163.  
  164.         move.l        d2,argslen                 ; save length of args
  165.         move.l        d3,proglen                 ; save length of prog
  166.         
  167.         movea.l       D4,A0                      ; Load program name
  168.         move.l        D3,D0                      ;      and length
  169.         move.b        #'"',(a3)+
  170.         bra.s         cpy1
  171. cpycmd: move.b        (A0)+,(A3)+                ; copy over the command name
  172. cpy1:   dbf           d0,cpycmd
  173.         move.b        #'"',(a3)+
  174.         move.b        #' ',(A3)+                 ; add the space delimiter
  175.  
  176.         move.l        A2,A0                      ; Load command text
  177.         move.l        D2,D0                      ;      and length
  178.         bra.s         cpy2
  179. cpylin: move.b        (A0)+,(A3)+
  180. cpy2:   dbf           d0,cpylin
  181.         clr.b         (A3)+
  182.  
  183. *------        Now copy over the program name
  184.         move.l        A3,_ProgramName(A4)
  185.         move.l        D4,A0
  186.         move.l        D3,D0
  187.         bra.s         cpy3
  188. cpypgm: move.b        (A0)+,(A3)+
  189. cpy3:   dbf           D0,cpypgm
  190.         clr.b         (A3)                        ;don't forget trailing null on name
  191.  
  192. *------ First we want to put it into our seglist
  193.         lea           segexit-copybeg(A1),A2
  194.         move.l        A2,_XCEXIT+2(A4)            ;patch the jump instruction
  195.         lea           start-4(PC),A2
  196.    
  197. *        Now we have:    A1 to our new fake segment
  198. *                        A2 to the start of the real seglist
  199.         move.l        #(copyend-copybeg)/4,(A1)+
  200.         move.l        A1,D3
  201.         lsr.l         #2,D3                        ;convert it to a bptr to the list
  202.         move.l        (A2),(A1)+                   ;save our next segment pointer
  203.         clr.l         (A2)                         ;and kill it from the chain
  204. *------ We have the seglist
  205.  
  206.         lea           AutoLoader(PC),A2
  207.         move.l        #(copyend-AutoLoader)-1,D0
  208. copyit  move.b        (A2)+,(A1)+
  209.         dbf           d0,copyit
  210.  
  211. *------        See if they want to do some I/O
  212.         tst.l        _BackGroundIO(A4)
  213.         beq          noio
  214.         lea          current_window(A4),A0
  215.         move.l       A0,D1
  216.         move.l       #1005,D2
  217.         move.l       DOSBase(A4),A6
  218.         callsys      Open
  219.         move.l       d0,_Backstdout(A4)
  220. noio:
  221.         move.l       AbsExecBase.w,A6
  222.  
  223. *------ If under 2.0 Flush cache
  224.    
  225.         moveq    #36,d0
  226.         cmp.w    $14(a6),d0
  227.         bgt.b    nocache
  228.         moveq    #-1,d0
  229.         callsys  CacheClearU
  230.  
  231. nocache:
  232.         
  233.         callsys        Forbid
  234.  
  235. *------ Attach the task to do the dirty work
  236.         move.l        __procname(A4),D1        ; Name of task to start
  237.         move.l        __priority(A4),D2        ; Priority of background task
  238.         move.l        __stack(A4),D4           ; Stack size of created task
  239.  
  240.         move.l        DOSBase(A4),A6
  241.         callsys       CreateProc
  242.         move.l        A6,A3                    ; restore dosbase to close it
  243.         tst.l         D0
  244.         bne           ok
  245.  
  246. *------ Serious problems.  For some reason the CreateProc failed.
  247. *------ We need to free the AlocEntry memory and go home
  248.         move.l        (A7)+,A2
  249.         movea.l       ML_SIZE+ME_ADDR(A2),A1   ;locate our allocated block
  250. *------ Also must get rid of current directory
  251.         move.l        __curdir(A4),D1
  252.         callsys       UnLock
  253.  
  254.         move.l        A2,A0
  255.         move.l        AbsExecBase.w,A6
  256.         callsys       FreeEntry
  257.         move.l        #104,D0
  258.         bra           cliexit
  259.  
  260. ok:
  261. *------ The task started ok, attach the memory we allocated to
  262. *------        its task control block
  263.         move.l        D0,A2
  264.  
  265.         move.l        (a7)+,A1                ;locate the memory we allocated
  266.         lea           -pr_MsgPort(A2),A2
  267.         lea           TC_MEMENTRY(A2),A0
  268.  
  269.  
  270. *        ADDTAIL
  271.         LEA           LH_TAIL(A0),A0
  272.         MOVE.L        LN_PRED(A0),D0
  273.         MOVE.L        A1,LN_PRED(A0)
  274.         MOVE.L        A0,(A1)
  275.         MOVE.L        D0,LN_PRED(A1)
  276.         MOVE.L        D0,A0
  277.         MOVE.L        A1,(A0)
  278.  
  279.         move.l        #0,D0
  280.  
  281. cliexit:
  282.         move.l        AbsExecBase.w,A6
  283.         callsys       Permit
  284.         move.l        A3,A1
  285.         move.l        AbsExecBase.w,A6
  286.         callsys       CloseLibrary
  287.         movem.l       (a7)+,d1-d6/a0-a6
  288.         rts
  289.  
  290. *=======================================================================
  291. *====== Workbench Startup Code =========================================
  292. *=======================================================================
  293.  
  294. fromWorkbench:
  295.  
  296.         move.l        TC_SPLOWER(A3),__base(A4)        ; set base of stack
  297.         add.l         #128,__base(A4)                  ;allow for parms overflow
  298. *------ open the DOS library:
  299.         bsr.w         openDOS
  300.  
  301.         lea           xcexit(PC),A2
  302.         move.l        A2,_XCEXIT+2(A4)                 ;patch the jump instruction
  303.         
  304. *------ we are now set up.  wait for a message from our starter
  305.         bsr.w         waitmsg
  306.         move.l        d0,_WBenchMsg(A4)
  307.         move.l        d0,-(SP)
  308. *
  309.         move.l        d0,a2                            ; get first argument
  310.         move.l        sm_ArgList(a2),d0
  311.         beq.s         do_cons
  312.         move.l        DOSBase(A4),a6
  313.         move.l        d0,a0
  314.         move.l        wa_Lock(a0),d1
  315.         callsys       DupLock
  316.         move.l        d0,__curdir(A4)
  317.         move.l        d0,d1
  318.         callsys       CurrentDir
  319. do_cons:
  320.         move.l        sm_ToolWindow(a2),d1             ; get the window argument
  321.         beq.s         do_main
  322.         move.l        #MODE_OLDFILE,d2
  323.         callsys       Open
  324.         move.l        d0,stdin(A4)
  325.         beq.s         do_main
  326.         lsl.l         #2,d0
  327.         move.l        d0,a0
  328.         move.l        fh_Type(a0),pr_ConsoleTask(A3)
  329. do_main:
  330.         move.l        _WBenchMsg(A4),a0                ; get address of workbench message
  331.         move.l        a0,-(a7)                         ; push argv
  332.         pea           NULL(A4)                         ; push argc
  333.         move.l        sm_ArgList(a0),a0                ; get address of arguments
  334.         move.l        wa_Name(a0),_ProgramName(A4)     ; get name of program
  335. *------ For startup from workbench, there is no reason to go through
  336. *------ The fancy stuff to make the startup work.  Just run the
  337. *------ Code directly
  338.         jsr           __fpinit(PC)
  339.         jsr           __main
  340.         moveq.l       #0,d0
  341.         bra.w         exit2
  342.         
  343.  
  344. ************************************************************************
  345. ************************************************************************
  346. *************                                              *************
  347. ************* Start of code that is copied to fake segment *************
  348. *************                                              *************
  349. ************************************************************************
  350. ************************************************************************
  351.  
  352. copybeg:
  353.         DC.L        (copyend-copybeg)/4
  354. next:   DC.L        0
  355. AutoLoader:
  356.         move.l        a7,d0
  357.         movem.l       d1-d6/a0-a6,-(a7)
  358.         move.l        d0,a5
  359.         move.l        AbsExecBase.w,a6
  360.         lea           LinkerDB,A4                ; load base register
  361.         move.l        a7,_StackPtr(A4)
  362.  
  363.         bsr.w         openDOS
  364.         suba.l        a1,a1
  365.  
  366.         suba.l        a1,a1
  367.         callsys       FindTask
  368.         move.l        d0,A3
  369.  
  370.         move.l        TC_SPLOWER(A3),__base(A4)        ; set base of stack
  371.         add.l         #128,__base(A4)          ;allow for parms overflow
  372.  
  373.         move.l        pr_SegList(A3),a0        ;locate the segment list
  374.         add.l         A0,A0
  375.         add.l         A0,A0                    ;and convert to an APTR
  376.         move.l        12(A0),A1                ;so we can access the segments
  377.         add.l         A1,A1
  378.         add.l         A1,A1
  379.  
  380.         move.l        (A1),seglist(A4)        ;save the remainder for later
  381.         move.l        (A1),12(A0)             ;cut off our segment
  382.  
  383.         move.l        __curdir(A4),D1
  384.         move.l        DOSBase(A4),a6
  385.         callsys       CurrentDir
  386.  
  387. *------ Open Nil: and set up it's input buffer so 
  388. *------ ReadArgs will work.
  389.         lea           nil(pc),a0
  390.         move.l        a0,d1
  391.         move.l        #MODE_OLDFILE,d2
  392.         callsys       Open
  393.         move.l        d0,pr_CIS(a3)
  394.         add.l         d0,d0
  395.         add.l         d0,d0
  396.         move.l        d0,a2
  397.         move.l        argslen(pc),d2
  398.         move.l        d2,fh_End(a2)
  399.         move.l        #0,fh_Pos(a2)        
  400.         
  401.         move.l        AbsExecBase.w,a6
  402.         move.l        d2,d0
  403.         moveq.l       #0,d1
  404.         callsys       AllocMem
  405.         tst.l         d0
  406.         beq.b         segexit
  407.  
  408.         move.l        d0,a0
  409.         lea           commandbuf(pc),a1
  410.         adda.l        proglen(pc),a1
  411.         addq.l        #3,a1               * 3 - is for quotes and trailing space
  412.         subq.l        #1,d2
  413.         blt.b         donecpy
  414. cpy:
  415.         move.b        (a1)+,(a0)+
  416.         dbf           d2,cpy        
  417.             
  418. donecpy:
  419.         lsr.l         #2,d0
  420.         move.l        d0,fh_Buf(a2)
  421.         
  422. *------ Use the cli that our creator set up for us.
  423.         move.l        cli(pc),pr_CLI(a3)
  424.  
  425.         jsr           __fpinit
  426.         pea           commandbuf(PC)
  427.         jsr           __main                        ; call C entrypoint
  428.         addq          #4,A7
  429.  
  430.  
  431. *------ Unlock the directory we set up for them
  432. segexit:
  433.         move.l        DOSBase(A4),a6
  434.         move.l        __curdir(A4),D1
  435.         callsys       UnLock
  436.  
  437.         moveq.l       #0,d0                        ; set successful status
  438. xcexit:
  439. exit2:
  440.         IFEQ          TINY
  441.         move.l        _ONEXIT(A4),d0                ; exit trap function?
  442.         beq.s         exit3
  443.         move.l        d0,a0
  444.         jsr           (a0)
  445.         ENDC
  446.  
  447. exit3:
  448. *------ These must not be PC relative calls since this code is copied
  449.         jsr           __fpterm
  450.         jsr           _MemCleanup                ; cleanup leftover memory alloc.
  451.  
  452.  
  453. done_1c:
  454. *------ if we ran from CLI, skip workbench cleanup:
  455.         tst.l         _WBenchMsg(A4)
  456.         beq.s         exitToDOS
  457.         move.l        DOSBase(A4),a6
  458.         move.l        stdin(A4),d1
  459.         beq.s         done_4
  460.         callsys       Close
  461. done_4:
  462.  
  463. *------ return the startup message to our parent
  464. *        we forbid so workbench can't UnLoadSeg() us
  465. *        before we are done:
  466.         move.l        __curdir(a4),d1
  467.         beq.s         done_5
  468.         callsys       UnLock
  469.  
  470. done_5:
  471.         move.l        AbsExecBase.w,A6
  472.         callsys       Forbid
  473.         move.l        _WBenchMsg(A4),a1
  474.         callsys       ReplyMsg
  475.         bra.b         noCIS
  476.  
  477. *------ this rts sends us back to DOS:
  478. exitToDOS:
  479.         jsr           __freecli
  480.         
  481.         move.l        AbsExecBase.W,a6
  482.         sub.l         a1,a1
  483.         callsys       FindTask
  484.         move.l        d0,a0
  485.         
  486.         move.l        pr_CIS(a0),d1      * test for our input file handle
  487.         beq.b         noCIS
  488.  
  489.         clr.l         pr_CIS(a0)
  490.         move.l        d1,d2
  491.         add.l         d1,d1
  492.         add.l         d1,d1
  493.         move.l        d1,a2
  494.         
  495. *------ First free the buffer we allocated
  496.         move.l        fh_Buf(a2),d1
  497.         add.l         d1,d1
  498.         add.l         d1,d1
  499.         move.l        d1,a1
  500.         move.l        argslen(pc),d0
  501.         callsys       FreeMem
  502.  
  503. *------ Restore fields to 0 
  504.         clr.l         fh_Buf(a2)
  505.         clr.l         fh_End(a2)
  506.  
  507. *------ Close Nil:        
  508.         move.l        d2,d1
  509.         move.l        DOSBase(A4),a6
  510.         callsys       Close
  511.  
  512. noCIS:
  513.         movea.l       _StackPtr(a4),a3            ; save old stack pointer 
  514.  
  515. *------ They are done so unload them
  516.         move.l        seglist(A4),D1
  517.         move.l        DOSBase(A4),a6
  518.         callsys       UnLoadSeg
  519.  
  520.         move.l        a6,a1
  521.         move.l        AbsExecBase.w,a6
  522.         callsys       CloseLibrary                ; close Dos library
  523.  
  524.  
  525.         movea.l       a3,SP                       ; restore stack ptr
  526.         movem.l       (a7)+,d1-d6/a0-a6
  527.         rts
  528.  
  529. *-----------------------------------------------------------------------
  530. *  Open the DOS library:
  531.  
  532. openDOS
  533.                 lea          DOSName(A4),A1
  534.                 moveq.l      #0,D0
  535.                 callsys      OpenLibrary
  536.                 move.l       D0,DOSBase(A4)
  537.                 beq          noDOS
  538.                 rts
  539. *-----------------------------------------------------------------------
  540. noDOS:
  541.                 moveq.l      #100,d0
  542.                 bra          exit2
  543.  
  544. cli:           dc.l         0
  545. argslen:        dc.l         0
  546. proglen:        dc.l         0
  547. nil:            dc.b         'NIL:',0,0
  548.                 
  549. copyend:
  550. commandbuf:
  551.  
  552. ************************************************************************
  553. ************************************************************************
  554. **************                                            **************
  555. ************** End of code that is copied to fake segment **************
  556. **************                                            **************
  557. ************************************************************************
  558. ************************************************************************
  559.  
  560. *-----------------------------------------------------------------------
  561. * This routine gets the message that workbench will send to us
  562. * called with task id in A3
  563.  
  564. waitmsg:
  565.                 lea        pr_MsgPort(A3),a0          ; our process base
  566.                 callsys    WaitPort
  567.                 lea        pr_MsgPort(A3),a0          ; our process base
  568.                 callsys    GetMsg
  569.                 rts
  570.  
  571.         csect        __MERGED,1,0,0,4
  572.  
  573. *------        These externals control the task that is started
  574.         xref        _BackGroundIO                ; flag to indicate background task
  575. *                                                ; wants to do I/O
  576.         xref        __stack                      ; stack space for created task
  577.         xref        __procname                   ; name of process to be created
  578.         xref        __priority                   ; priority to create process at
  579.  
  580.         xref        DOSBase
  581.         xref        MathBase
  582.         xref        MathTransBase
  583. *
  584.         xdef        NULL,SysBase,_WBenchMsg
  585.         xdef        __curdir
  586.         xdef        _OSERR,_FPERR,_SIGFPE,_ONERR,_ONEXIT,_ONBREAK
  587.         xdef        _SIGINT,_Backstdout
  588.         xdef        _ProgramName,_StackPtr,__base
  589. *
  590. memlist        ds.b        LN_SIZE
  591.                dc.w        1
  592.                dc.l        MEMF_PUBLIC
  593. memsize        dc.l        copyend-copybeg
  594.  
  595. _XCEXIT      
  596. @_XCEXIT       dc.w        $4ef9
  597.                dc.l        0
  598. seglist        dc.l        0
  599. NULL           dc.l        0                ;
  600. __base         dc.l        0                ; base of stack
  601. _OSERR         dc.l        0
  602. _FPERR         dc.l        0
  603. _SIGFPE        dc.l        0
  604. _SIGINT        dc.l        0
  605. _ONERR         dc.l        0
  606. _ONEXIT        dc.l        0
  607. _ONBREAK       dc.l        0
  608. __curdir       dc.l        0
  609. SysBase        dc.l        0
  610. _WBenchMsg     dc.l        0
  611. _StackPtr      dc.l        0
  612. dosCmdLen      dc.l        0
  613. dosCmdBuf      dc.l        0
  614. stdin          dc.l        0
  615. _Backstdout    dc.l        0                ;filehandle for I/O
  616. _ProgramName   dc.l        0
  617. DOSName        dc.b        'dos.library',0
  618. current_window dc.b        '*',0
  619.                END
  620.